/**
 *
 */

export class StringUtils {
  /**
   *
   * @param arg {String |  Number}
   * @return {boolean}
   */
  static isEmptyOrNull(arg) {
    const _v = arg + ''
    let res = false
    if (_v === 'undefined' || _v === 'null' || _v === '') {
      res = true
    }

    return res
  }

  static emptyMsg(value, text) {
    return StringUtils.isEmptyOrNull(value) ? text : value
  }

  /**
   * 去空格
   * @param str
   * @return {string}
   */
  static trimString(str) {
    const reTrim = /^\s+|\s+$/g
    return StringUtils.getString(str).replace(reTrim, '')
  }

  /**
   *
   * @param s
   * @return {string|string}
   */
  static getString(s) {
    let res
    if (StringUtils.isEmptyOrNull(s)) {
      res = ''
    } else {
      res = s
    }

    if (StringUtils.isJson(s)) {
      res = StringUtils.parseJson(s, null)
    }

    return res + ''
  }

  static isNumber(value) {
    const rdf = /(^(0|[+-]?((0|([1-9]\d*))\.\d+)?)$)/
    const rdd = /^[+-]?(0|([1-9]\d*))(\.\d+)?$/
    const sinetific = /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/

    const res = rdf.test(value) || rdd.test(value) || sinetific.test(value)

    return res
  }

  static findNumbers(value) {
    const text = value
    const regex = /[+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/g
    let match
    const numbers = []
    while ((match = regex.exec(text)) !== null) {
      numbers.push(match[0])
    }

    return numbers
  }

  static inputNumber(value) {
    // // const regex = /^[+-]?\d*\.?\d+(?:[eE][+-]?\d*)?$/; //整数
    const text = value
    const regex = /^[+-]?\d*\.?(\d+)?(?:[eE][+-]?\d*)?$/gi
    const result = regex.test(text) || StringUtils.isEmptyOrNull(text)

    return result
  }

  static camel2sneak(str, upper) {
    if (!str) return ''

    return String(str)
      .replace(/^[^A-Za-z0-9]*|[^A-Za-z0-9]*$/g, '')
      .replace(/([a-z])([A-Z])/g, (m, a, b) => a + '_' + b.toLowerCase())
      .replace(/[^A-Za-z0-9]+|_+/g, '_')
      .toLowerCase()
  }

  static toCamelCase(str = '') {
    if (!str) return ''

    return String(str)
      .replace(/^[^A-Za-z0-9]*|[^A-Za-z0-9]*$/g, '')
      .replace(/[^A-Za-z0-9]+/g, '$')
      .replace(/([a-z])([A-Z])/g, (m, a, b) => `${a}$${b}`)
      .toLowerCase()
      .replace(/(\$)(\w)/g, (m, a, b) => b.toUpperCase())
  }

  /**
   *
   * @param i_value {string | Number}
   * @param {Number}  [fixed] 保留小数位
   * @param {string} [null_str] optional 不填则为空字符串
   * @return {Number | String}  返回null_str的值
   */
  static getNumber(i_value, fixed, null_str) {
    const _num = Number(i_value)
    const _fixed = Number(fixed)
    const isNan = isNaN(_num)
    const isFixedNaN = isNaN(fixed)

    let res
    if (isNan || StringUtils.isEmptyOrNull(i_value)) {
      return null_str || ''
    }

    if (!isNan && !StringUtils.isEmptyOrNull(i_value)) {
      res = +_num
    }

    if (!StringUtils.isEmptyOrNull(_fixed) && !isFixedNaN && _fixed > 0) {
      res = +_num.toFixed(_fixed)
    }

    if (_fixed === 0) {
      res = +_num
    }

    return res
  }

  static zeroReplace(value, rvalue, fixed) {
    const v = StringUtils.getNumber(value, fixed || 2, rvalue).toFixed(fixed)
    return v === 0 ? rvalue : v
  }

  static getNumberExceptZero(num, toFixed) {
    const _absNum = StringUtils.getNumber(num, toFixed, 'null')
    return _absNum === 0 || num === 'null' ? null : _absNum
  }

  static getNumberExceptZeroArray(array = [], toFixed = 2) {
    const res = []
    array.forEach((num) => {
      const _absNum = StringUtils.getNumber(num, toFixed, 'null')
      const isZero = _absNum === 0 || num === 'null' ? null : _absNum
      if (!isZero) res.push(num)
    })

    return res
  }

  static roundTo(value, to) {
    if (StringUtils.isEmptyOrNull(value)) {
      throw new Error('value is not defined')
    }
    const valueNumber = Number(value)
    if (isNaN(valueNumber)) {
      throw new Error('value is NaN')
    }

    const floor = 10
    const valueFloored = valueNumber % floor

    let f_value = to - valueFloored
    if (f_value < 0) {
      f_value = floor - valueFloored
    }
    const res = valueNumber + f_value
    return res
  }

  static uuid() {
    let s = []
    let hexDigits = '0123456789abcdef'
    for (let i = 0; i < 32; i++) {
      s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
    }
    // bits 12-15 of the time_hi_and_version field to 0010
    s[14] = '4'
    // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
    // s[8] = s[13] = s[18] = s[23] = "-";
    let uuid = s.join('')
    return uuid
  }

  /**
   * 判断合法json
   * @param {String} str json字符串
   * @return {Boolean}
   */
  static isJson(str) {
    let isJSON = true
    let json
    try {
      json = JSON.parse(str)
    } catch (e) {
      isJSON = false
    }

    return isJSON && json
  }

  /**
   *
   * @param {String} str json字符串
   * @param {Array | Object | String} expect_value  默认为 0
   * @return {number | Object | Array}
   */
  static parseJson(str, expect_value) {
    if (!StringUtils.isJson(str)) {
      if (expect_value === null) {
        return null
      }
      return expect_value || 0
    }
    return JSON.parse(str)
  }
}
